package com.upcode.weighing.detect.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.upcode.weighing.base.controller.BaseController;
import com.upcode.weighing.detect.service.DetectPointService;
import com.upcode.weighing.domain.DetectPoint;
import com.upcode.weighing.log.OpsLog;
import com.upcode.weighing.util.NumberUtil;
import com.upcode.weighing.vo.req.*;
import com.upcode.weighing.vo.resp.BaseResponseVo;
import com.upcode.weighing.vo.resp.DetectPointRespVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author alex
 * @since 2024-07-21
 */
@Controller
@RequestMapping("/detectpoint")
@Api(value = "/detectpoint",description = "检测点接口",produces = MediaType.ALL_VALUE,tags = {"检测点接口"})
public class DetectPointController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(DetectPointController.class);
    @Autowired
    private DetectPointService detectPointService;

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 新增系统账号
     */
    @OpsLog(operation = "检测点接口/添加检测点" ,type = 2)
    @PostMapping("/add")
    @ApiOperation(value = "添加检测点", notes = "添加", httpMethod = "POST")
    public Object add(@Validated @RequestBody DetectPointAddVo detectPointAddVo) {
        DetectPoint detectPoint=new DetectPoint();
        BeanUtils.copyProperties(detectPointAddVo,detectPoint);
        detectPoint.setId(IdWorker.getId());
        //取uuid的前6个字符作为秘钥
        detectPoint.setUploadAuthCode(NumberUtil.uuid().substring(0,6));
        try{
            detectPointService.saveOrUpdate(detectPoint);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            return error(e.getMessage());
        }

        return success("添加检测记录成功");
    }
    /**
     * 获取检测记录分页列表
     */
    @OpsLog(operation = "检测点接口/分页查询" ,type = 1)
    @PostMapping("/queryPage")
    @ApiOperation(value = "检测点分页查询",notes = "")
    public ResponseEntity<BaseResponseVo<IPage<DetectPointRespVo>>> queryPage(@RequestBody PageReqVo<DetectPointQueryParam> queryParamPageReqVo){
        IPage<DetectPointRespVo> page = detectPointService.queryPageList(queryParamPageReqVo);
        return  HttpResponse.success(page);
    }

    /**
     * 获取检测点列表
     */
    @OpsLog(operation = "检测点接口/列表查询" ,type = 1)
    @PostMapping("/queryList")
    @ApiOperation(value = "检测点查询",notes = "")
    public  ResponseEntity<BaseResponseVo<List<DetectPointRespVo>>> queryList(@RequestBody DetectPointQueryParam detectPointQueryParam){
        List<DetectPointRespVo> detectPointList = detectPointService.queryList(detectPointQueryParam);
        return HttpResponse.success(detectPointList);
    }
    /**
     *查询账号详情
     */
    @GetMapping("/detail/{id}")
    @ApiOperation(value = "检测点接口/查看详情" , notes = "")
    public  ResponseEntity<BaseResponseVo<DetectPointRespVo>> details(@PathVariable("id")@NotNull(message = "id 不能为空") Long userId){
        DetectPoint detectPoint = detectPointService.getById(userId);
        DetectPointRespVo detectPointRespVo=new DetectPointRespVo();
        BeanUtils.copyProperties(detectPoint,detectPointRespVo);
        return HttpResponse.success(detectPointRespVo);
    }

    /**
     * 根据id修改信息
     */
    @OpsLog(operation = "检测记录接口/更新检测点" ,type = 4)
    @PostMapping("/update")
    @ApiOperation(value = "更新检测点" ,notes = "")
    public Object updateById(@Validated @RequestBody DetectPointEditVo detectPointEditVo){
        DetectPoint detectPoint=new DetectPoint();
        BeanUtils.copyProperties(detectPointEditVo,detectPoint);
        try {
            if(!detectPointService.updateById(detectPoint)){
                return error("修改失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(e.getMessage());
        }
        return success("修改成功");
    }

    /**
     * 根据id修改删除
     */
    @OpsLog(operation = "删除" ,type = 4)
    @PostMapping("/delete/{id}")
    @ApiOperation(value = "检测记录删除" ,notes = "")
    public Object delete(@PathVariable("id")@NotNull(message = "id 不能为空") Long id){
        try {
            if(!detectPointService.removeById(id)){
                return error("删除失败");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return error(e.getMessage());
        }
        return success("删除成功");
    }

    /**
     * 新增系统账号
     */
    @OpsLog(operation = "检测点接口/检测点添加心跳" ,type = 2)
    @PostMapping("/addHeartbeat")
    @ApiOperation(value = "检测点添加心跳", notes = "添加", httpMethod = "POST")
    public Object addHeartbeat(@Validated @RequestBody DetectPointHeartbeat detectPointHeartbeat) {
        logger.debug("添加心跳:"+detectPointHeartbeat.toString());
        DetectPoint detectPoint = detectPointService.getById(detectPointHeartbeat.getPointId());
        if (detectPoint.getStatus() == null || detectPoint.getStatus() == 0) {
            detectPoint.setOnlineStartTime(LocalDateTime.now());
            long offlineDuration;
            if (detectPoint.getLastOfflineTime() != null) {//如果有最近一次离线时间,就使用最近一次离线时间计算时间差
                offlineDuration = Duration.between(detectPoint.getLastOfflineTime(), LocalDateTime.now()).toMillis() / 1000;
            } else {//如果没有最近一次离线时间,就使用创建时间计算时间差
                offlineDuration = Duration.between(detectPoint.getCreateTime(), LocalDateTime.now()).toMillis() / 1000;
            }
            detectPoint.setOfflineDuration(offlineDuration);
        }
        detectPoint.setStatus(1);//在线
        detectPoint.setLastHeartbeatTime(LocalDateTime.now());
        BeanUtils.copyProperties(detectPointHeartbeat,detectPoint);
        try{
            detectPointService.saveOrUpdate(detectPoint);
            int timeout=20*60;//设置心跳保留时间20分钟
            redisTemplate.opsForValue().set("heartbeart_"+detectPoint.getId(), detectPoint.getStatus(), timeout, TimeUnit.SECONDS);
            logger.debug("设置心跳超时时间为:"+timeout+"秒");
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            return error(e.getMessage());
        }

        return success("添加检测点心跳");
    }
}
